using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using System.Text;
using System.Linq;

namespace GenerativeAgents.Core
{
    /// <summary>
    /// 嵌入引擎接口
    /// 负责生成文本的语义嵌入向量
    /// </summary>
    public interface IEmbeddingEngine
    {
        Task<float[]> GenerateEmbeddingAsync(string text);
        float[] GenerateEmbedding(string text);
        float CalculateSimilarity(float[] embedding1, float[] embedding2);
        int EmbeddingDimension { get; }
    }
    
    /// <summary>
    /// 语言模型接口
    /// 负责生成自然语言响应和进行推理
    /// </summary>
    public interface ILanguageModel
    {
        Task<string> GenerateResponseAsync(string prompt, float temperature = 0.7f, int maxTokens = 150);
        string GenerateResponse(string prompt, float temperature = 0.7f, int maxTokens = 150);
        Task<int> ScoreImportanceAsync(string eventDescription);
        int ScoreImportance(string eventDescription);
        Task<List<string>> ExtractKeywordsAsync(string text, int maxKeywords = 5);
        List<string> ExtractKeywords(string text, int maxKeywords = 5);
    }
    
    /// <summary>
    /// 简化的嵌入引擎实现
    /// 使用预计算的词向量和简单的文本处理
    /// </summary>
    public class SimpleEmbeddingEngine : MonoBehaviour, IEmbeddingEngine
    {
        [Header("嵌入配置")]
        public int embeddingDimension = 256;
        public bool usePrecomputedEmbeddings = true;
        
        private Dictionary<string, float[]> wordEmbeddings;
        private Dictionary<string, float[]> cachedEmbeddings;
        private System.Random random;
        
        public int EmbeddingDimension => embeddingDimension;
        
        private void Awake()
        {
            InitializeEmbeddingEngine();
        }
        
        private void InitializeEmbeddingEngine()
        {
            wordEmbeddings = new Dictionary<string, float[]>();
            cachedEmbeddings = new Dictionary<string, float[]>();
            random = new System.Random();
            
            // 加载预定义的词向量（简化实现）
            LoadPrecomputedEmbeddings();
        }
        
        /// <summary>
        /// 异步生成文本嵌入
        /// </summary>
        public async Task<float[]> GenerateEmbeddingAsync(string text)
        {
            return await Task.Run(() => GenerateEmbedding(text));
        }
        
        /// <summary>
        /// 生成文本嵌入
        /// </summary>
        public float[] GenerateEmbedding(string text)
        {
            if (string.IsNullOrEmpty(text))
                return new float[embeddingDimension];
            
            // 检查缓存
            if (cachedEmbeddings.TryGetValue(text, out var cached))
                return cached;
            
            var embedding = ComputeTextEmbedding(text);
            
            // 缓存结果
            if (cachedEmbeddings.Count < 1000) // 限制缓存大小
            {
                cachedEmbeddings[text] = embedding;
            }
            
            return embedding;
        }
        
        /// <summary>
        /// 计算余弦相似度
        /// </summary>
        public float CalculateSimilarity(float[] embedding1, float[] embedding2)
        {
            if (embedding1 == null || embedding2 == null)
                return 0f;
            
            if (embedding1.Length != embedding2.Length)
                return 0f;
            
            float dotProduct = 0f;
            float norm1 = 0f;
            float norm2 = 0f;
            
            for (int i = 0; i < embedding1.Length; i++)
            {
                dotProduct += embedding1[i] * embedding2[i];
                norm1 += embedding1[i] * embedding1[i];
                norm2 += embedding2[i] * embedding2[i];
            }
            
            if (norm1 == 0f || norm2 == 0f)
                return 0f;
            
            return dotProduct / (Mathf.Sqrt(norm1) * Mathf.Sqrt(norm2));
        }
        
        /// <summary>
        /// 计算文本嵌入
        /// </summary>
        private float[] ComputeTextEmbedding(string text)
        {
            var words = PreprocessText(text);
            var embedding = new float[embeddingDimension];
            
            if (words.Count == 0)
                return embedding;
            
            // 平均词向量法
            int validWords = 0;
            foreach (var word in words)
            {
                if (wordEmbeddings.TryGetValue(word.ToLower(), out var wordVector))
                {
                    for (int i = 0; i < embeddingDimension; i++)
                    {
                        embedding[i] += wordVector[i];
                    }
                    validWords++;
                }
                else
                {
                    // 为未知词生成随机向量
                    var randomVector = GenerateRandomVector(word);
                    for (int i = 0; i < embeddingDimension; i++)
                    {
                        embedding[i] += randomVector[i];
                    }
                    validWords++;
                }
            }
            
            // 平均化
            if (validWords > 0)
            {
                for (int i = 0; i < embeddingDimension; i++)
                {
                    embedding[i] /= validWords;
                }
            }
            
            // 归一化
            return NormalizeVector(embedding);
        }
        
        /// <summary>
        /// 文本预处理
        /// </summary>
        private List<string> PreprocessText(string text)
        {
            var words = new List<string>();
            var cleanText = text.ToLower()
                .Replace(".", "")
                .Replace(",", "")
                .Replace("!", "")
                .Replace("?", "")
                .Replace("\"", "")
                .Replace("'", "");
            
            var tokens = cleanText.Split(new char[] { ' ', '\t', '\n' }, StringSplitOptions.RemoveEmptyEntries);
            
            // 移除停用词
            var stopWords = new HashSet<string> { "the", "a", "an", "and", "or", "but", "in", "on", "at", "to", "for", "of", "with", "by", "is", "was", "are", "were", "be", "been", "have", "has", "had", "do", "does", "did", "will", "would", "could", "should" };
            
            foreach (var token in tokens)
            {
                if (token.Length > 1 && !stopWords.Contains(token))
                {
                    words.Add(token);
                }
            }
            
            return words;
        }
        
        /// <summary>
        /// 为单词生成随机向量（基于hash）
        /// </summary>
        private float[] GenerateRandomVector(string word)
        {
            var vector = new float[embeddingDimension];
            var hash = word.GetHashCode();
            var rng = new System.Random(hash);
            
            for (int i = 0; i < embeddingDimension; i++)
            {
                vector[i] = (float)(rng.NextDouble() * 2.0 - 1.0); // -1 到 1 之间
            }
            
            return NormalizeVector(vector);
        }
        
        /// <summary>
        /// 向量归一化
        /// </summary>
        private float[] NormalizeVector(float[] vector)
        {
            float norm = 0f;
            for (int i = 0; i < vector.Length; i++)
            {
                norm += vector[i] * vector[i];
            }
            
            norm = Mathf.Sqrt(norm);
            if (norm > 0f)
            {
                for (int i = 0; i < vector.Length; i++)
                {
                    vector[i] /= norm;
                }
            }
            
            return vector;
        }
        
        /// <summary>
        /// 加载预计算的词嵌入
        /// </summary>
        private void LoadPrecomputedEmbeddings()
        {
            // 预定义一些常用词的向量（简化实现）
            var commonWords = new string[]
            {
                "move", "walk", "run", "sit", "stand", "talk", "speak", "listen", "see", "look",
                "eat", "drink", "sleep", "wake", "work", "play", "read", "write", "think", "feel",
                "happy", "sad", "angry", "excited", "tired", "hungry", "thirsty", "comfortable", "nervous", "calm",
                "friend", "person", "people", "family", "home", "house", "room", "kitchen", "bedroom", "office",
                "morning", "afternoon", "evening", "night", "today", "yesterday", "tomorrow", "time", "day", "week",
                "like", "love", "hate", "want", "need", "know", "understand", "remember", "forget", "learn"
            };
            
            foreach (var word in commonWords)
            {
                wordEmbeddings[word] = GenerateRandomVector(word);
            }
        }
        
        /// <summary>
        /// 清理缓存
        /// </summary>
        public void ClearCache()
        {
            cachedEmbeddings.Clear();
        }
        
        /// <summary>
        /// 获取缓存统计信息
        /// </summary>
        public string GetCacheStats()
        {
            return $"Cached embeddings: {cachedEmbeddings.Count}, Word embeddings: {wordEmbeddings.Count}";
        }
    }
}